package com.example.demo.groovy;

import com.example.demo.config.DemoLoggerFactory;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.apache.commons.codec.digest.DigestUtils;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class GroovyUtilsFactory {
    private static final Logger log = DemoLoggerFactory.getServerInfoLogger(GroovyUtilsFactory.class);

    private static GroovyShell groovyShell;

    private static Map<String, Script> scriptCache = new ConcurrentHashMap<>();

    public GroovyUtilsFactory() {
        log.info("1111111111111");
        Binding binding = new Binding();
        binding.setVariable("log", log);
        groovyShell = new GroovyShell(binding);
    }

    public <T> T invoke(String scriptText, String function, Object... objects) throws Exception {
        log.info("Groovy function: {}", function);
        log.info("Groovy objects: {}", objects);
        Script script;
        String cacheKey = DigestUtils.md5Hex(scriptText);

        if (scriptCache.containsKey(cacheKey)) {
            script = scriptCache.get(cacheKey);
        } else {
            script = groovyShell.parse(scriptText);
            scriptCache.put(cacheKey, script);
        }

        T res =  (T) InvokerHelper.invokeMethod(script, function, objects);
        log.info("Groovy res: {}", res);
        return res;
    }
}
